package com.ctg.behavior.calc.impala.calculator;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.calc.common.CtSQLParam;
import com.ctg.behavior.calc.impala.CtCalculator;
import com.ctg.behavior.calc.impala.builder.CtPropertyValuesBuilder;
import com.ctg.behavior.calc.impala.builder.properties.CtUesrPropertyBuilder;
import com.ctg.behavior.calc.impala.engine.ImpalaSQLEngine;
import com.ctg.behavior.calc.impala.transfer.property.CtPropertyValuesTransfer;
import com.ctg.behavior.calc.impala.transfer.property.CtUserPropertiesTransfer;
import com.ctg.behavior.calc.impala.utils.CtCalculatorUtils;
import com.ctg.behavior.client.impala.common.CtQueryResult;
import com.ctg.behavior.common.CtgMapData;
import com.ctg.behavior.common.calc.CtCalcBody;
import com.ctg.behavior.common.calc.CtCalcResult;
import com.ctg.behavior.common.calc.CtCalcStatusResult;
import com.ctg.behavior.common.consts.CtCalcTaskConsts;
import com.ctg.behavior.common.properties.CtPropertyValuesCalcBody;
import com.ctg.behavior.common.properties.CtPropertyValuesCalcResult;
import com.ctg.behavior.common.properties.CtUserPropertiesCalcBody;
import com.ctg.behavior.common.properties.CtUserPropertiesCalcResult;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CtPropertyCalculator implements CtCalculator {

	@Autowired
	private ImpalaSQLEngine sqlEngine;
	@Autowired
	private CtPropertyValuesTransfer propertyValuesTransfer;
	@Autowired
	private CtPropertyValuesBuilder propertyValuesBuilder;
	
	@Autowired
	private CtUserPropertiesTransfer userPropertiesTransfer;
	@Autowired
	private CtUesrPropertyBuilder uesrPropertyBuilder;
	

	@Override
	public CtCalcResult doCalculator(CtCalcBody calcBody) {

		if (calcBody instanceof CtPropertyValuesCalcBody) {
			// 事件或用户对应的属性值计算接口
			return this.doPropertyValuesCalculator(calcBody);
		}

		if (calcBody instanceof CtUserPropertiesCalcBody) {
			// 单个用户(设备)对应的属性值计算接口
			return this.doUserPropertiesCalculator(calcBody);
		}

		{
			CtCalcStatusResult calcResult = new CtCalcStatusResult();
			log.error("calcBody={}", calcBody.getClass());
			calcResult.setSuccess(false);
			calcResult.setErrorCode("400");
			calcResult.setErrorMessage("param error");
			return calcResult;
		}

	}

	public CtPropertyValuesCalcResult doPropertyValuesCalculator(CtCalcBody calcBody) {

		CtPropertyValuesCalcResult calcResult = new CtPropertyValuesCalcResult();

		log.info("calcBody={}", calcBody);
		if (!(calcBody instanceof CtPropertyValuesCalcBody)) {
			log.error("calcBody={}", calcBody.getClass());
			calcResult.setSuccess(false);
			calcResult.setErrorCode("400");
			calcResult.setErrorMessage("param error");
			return calcResult;
		}
		CtPropertyValuesCalcBody propertyCalcBody = (CtPropertyValuesCalcBody) calcBody;
		log.info("calcBody={}", propertyCalcBody);

		String queryType = CtCalcTaskConsts.TASK_TYPE_PROPERTIES;
		CtSQLParam sqlParam = new CtSQLParam();
		String sql = propertyValuesTransfer.doTransfer(propertyCalcBody, sqlParam);
		log.info("sql={}", sql);
		if (StringUtils.isEmpty(sql)) {
			return calcResult;
		}
		CtQueryResult queryResult = sqlEngine.doQuery(queryType, sql);
		log.info("queryResult={}", JSON.toJSONString(queryResult));

		CtCalculatorUtils.fillCalcResult(calcResult, queryResult);
		if (!calcResult.getSuccess()) {
			log.error(queryResult.getCode());
		}

		calcResult = propertyValuesBuilder.doBuilder(calcResult, queryResult.getRows());
		log.info("calcResult={}", calcResult);

		return calcResult;
	}

	public CtUserPropertiesCalcResult doUserPropertiesCalculator(CtCalcBody calcBody) {
		CtUserPropertiesCalcResult calcResult = new CtUserPropertiesCalcResult();
		calcResult.setValue(new CtgMapData());

		log.info("calcBody={}", calcBody);
		if (!(calcBody instanceof CtUserPropertiesCalcBody)) {
			log.error("calcBody={}", calcBody.getClass());
			calcResult.setSuccess(false);
			calcResult.setErrorCode("400");
			calcResult.setErrorMessage("param error");
			return calcResult;
		}
		CtUserPropertiesCalcBody propertyCalcBody = (CtUserPropertiesCalcBody) calcBody;
		log.info("calcBody={}", propertyCalcBody);

		String sql = userPropertiesTransfer.doTransfer(propertyCalcBody, CtSQLParam.createParam());
		log.info("sql={}", sql);
		if (StringUtils.isEmpty(sql)) {
			return calcResult;
		}
		
		String queryType = CtCalcTaskConsts.TASK_TYPE_PROPERTIES;
		CtQueryResult queryResult = sqlEngine.doQuery(queryType, sql);
		log.info("queryResult={}", JSON.toJSONString(queryResult));

		CtCalculatorUtils.fillCalcResult(calcResult, queryResult);
		if (!calcResult.getSuccess()) {
			log.error(queryResult.getCode());
		}

		calcResult = uesrPropertyBuilder.doBuilder(calcResult, queryResult.getRows(), propertyCalcBody);
		log.info("calcResult={}", calcResult);
		
		return calcResult;
	}
}
